package com.bsg.upm.service;

import java.text.MessageFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.http.HttpStatus;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bsg.upm.constant.SysConstants;
import com.bsg.upm.dao.ClusterDao;
import com.bsg.upm.dao.HostDao;
import com.bsg.upm.dao.PortDao;
import com.bsg.upm.dao.ServDao;
import com.bsg.upm.entity.ClusterEntity;
import com.bsg.upm.entity.HostEntity;
import com.bsg.upm.exception.APIException;
import com.bsg.upm.http.RespJson;
import com.bsg.upm.http.RespJsonFactory;

/**
 * 
 * @author yucs
 *
 */
@Service
public class MonitorSiteService extends BaseService {
	@Resource
	private ClusterDao clusterDao;

	@Resource
	private HostDao hostDao;

	@Resource
	private PortDao portDao;

	@Resource
	private ServDao servDao;

	public RespJson getClusterInfo(String siteId) throws APIException {
		try {
			JSONArray retJsonArray = new JSONArray();

			Map<String, Object> paramMap = new HashMap<String, Object>();
			paramMap.put("siteId", siteId);
			List<ClusterEntity> clusters = clusterDao.list(paramMap);
			if (clusters.size() == 0) {
				return RespJsonFactory.buildOK(retJsonArray);
			}

			JSONArray mgmHostInfos = listHostInfoFromMGM(siteId);
			Map<String, Object> clusterInfos = mergeClusterInfo(mgmHostInfos);

			for (ClusterEntity cluster : clusters) {
				JSONObject clusterCpuAllObj = new JSONObject();
				clusterCpuAllObj.put("relate_id", cluster.getRelateId());
				clusterCpuAllObj.put("id", cluster.getId());
				clusterCpuAllObj.put("name", cluster.getName());
				
				if (!clusterInfos.containsKey(cluster.getRelateId())) {
					clusterCpuAllObj.put("cpu_all", 0);
					clusterCpuAllObj.put("cpu_free", 0);
					clusterCpuAllObj.put("memory_free", 0);
					clusterCpuAllObj.put("memory_all", 0);
					clusterCpuAllObj.put("containerCnt", 0);
					
					retJsonArray.add(clusterCpuAllObj);
					continue;
				}

				String key = cluster.getRelateId() + "cpu_all";
				clusterCpuAllObj.put("cpu_all", clusterInfos.get(key));

				key = cluster.getRelateId() + "cpu_free";
				clusterCpuAllObj.put("cpu_free", clusterInfos.get(key));

				key = cluster.getRelateId() + "memory_free";
				clusterCpuAllObj.put("memory_free", clusterInfos.get(key));

				key = cluster.getRelateId() + "memory_all";
				clusterCpuAllObj.put("memory_all", clusterInfos.get(key));

				clusterCpuAllObj.put("containerCnt", clusterInfos.get(cluster.getRelateId() + "containerCnt"));

				retJsonArray.add(clusterCpuAllObj);
			}
			
			
			return RespJsonFactory.buildOK(retJsonArray);
		} catch (Exception e) {
			logger.error("获取集群主机信息异常", e);
			throw new APIException("获取集群主机信息异常" + e.getMessage());

		}

	}

	public RespJson getHostInfo(String clusterId) throws APIException {
		try {

			JSONArray HostInfoArr = new JSONArray();

			ClusterEntity cluster = clusterDao.get(clusterId);
			if (cluster == null) {
				return RespJsonFactory.build(HttpStatus.SC_GONE, "该集群不存在");
			}

			Map<String, Object> searchParamMap = new HashMap<String, Object>();
			searchParamMap.put("clusterId", clusterId);
			List<HostEntity> hosts = hostDao.list(searchParamMap);
			if (hosts.size() == 0) {
				return RespJsonFactory.buildOK(HostInfoArr);
			}

			String siteId = cluster.getArea().getSite().getId();
			Map<String, JSONObject> mgmHostInfoMap = getHostInfoMapFromMGM(siteId);

			for (HostEntity host : hosts) {
				JSONObject hostInfo = new JSONObject();

				hostInfo.put("name", host.getName());
				hostInfo.put("id", host.getId());
				hostInfo.put("relate_id", host.getRelateId());

				if (mgmHostInfoMap.containsKey(host.getRelateId())) {
					JSONObject mgmHostInfo = mgmHostInfoMap.get(host.getRelateId());

					hostInfo.put("cpu_free", mgmHostInfo.getJSONObject("Engine").getInteger("free_cpus"));
					hostInfo.put("memory_free", mgmHostInfo.getJSONObject("Engine").getLong("free_memory"));

					 JSONArray containerInfos = getContainersFromHost(mgmHostInfo);
					 hostInfo.put("containers", containerInfos);

				}

				HostInfoArr.add(hostInfo);
			}

			return RespJsonFactory.buildOK(HostInfoArr);
		} catch (Exception e) {
			logger.error("集群主机信息获取异常", e);
			throw new APIException("集群主机信息获取异常:" + e.getMessage());
		}
	}

	 private JSONArray getContainersFromHost(JSONObject hostInfo) {
	 JSONArray containers = new JSONArray();
	
	 for (Object tmp : hostInfo.getJSONArray("containers")) {
	 JSONObject container = (JSONObject) tmp;
	 JSONObject containerInfo = new JSONObject();
	 
	 containerInfo.put("container_name",container.getString("name"));
	 containerInfo.put("cpu", container.getInteger("ncpu"));
	 containerInfo.put("memory", container.getLong("memory"));
	
	 containers.add(containerInfo);
	
	 }
	
	 return containers;
	 }

	private Map<String, Object> mergeClusterInfo(JSONArray mgmHostInfos) {
		Map<String, Object> maps = new HashMap<String, Object>();

		for (Object tmp : mgmHostInfos) {

			JSONObject host = (JSONObject) tmp;
			String clusterId = host.getString("cluster_id");

			if (!maps.containsKey(clusterId)) {
				maps.put(clusterId, clusterId);
			}

			String cpuAllkey = clusterId + "cpu_all";
			if (!maps.containsKey(cpuAllkey)) {
				maps.put(cpuAllkey, new Integer(0));
			}
			maps.put(cpuAllkey, (Integer) maps.get(cpuAllkey) + host.getJSONObject("Engine").getInteger("cpus"));

			String cpuFreeKey = clusterId + "cpu_free";
			if (!maps.containsKey(cpuFreeKey)) {
				maps.put(cpuFreeKey, new Integer(0));
			}
			maps.put(cpuFreeKey, (Integer) maps.get(cpuFreeKey) + host.getJSONObject("Engine").getInteger("free_cpus"));

			String memAllkey = clusterId + "memory_all";
			if (!maps.containsKey(memAllkey)) {
				maps.put(memAllkey, new Long(0));
			}
			maps.put(memAllkey, (Long) maps.get(memAllkey) + host.getJSONObject("Engine").getLong("memory"));

			String memFreekey = clusterId + "memory_free";
			if (!maps.containsKey(memFreekey)) {
				maps.put(memFreekey, new Long(0));
			}
			maps.put(memFreekey, (Long) maps.get(memFreekey) + host.getJSONObject("Engine").getLong("free_memory"));

			String contaierkey = clusterId + "containerCnt";
			if (!maps.containsKey(contaierkey)) {
				maps.put(contaierkey, new Long(0));
			}
			maps.put(contaierkey, (Long) maps.get(contaierkey) + host.getJSONArray("containers").size());

		}

		return maps;
	}

	private Map<String, JSONObject> getHostInfoMapFromMGM(String siteId) throws APIException {
		Map<String, JSONObject> maps = new HashMap<String, JSONObject>();
		JSONArray mgmHostInfos = listHostInfoFromMGM(siteId);

		for (Object tmp : mgmHostInfos) {
			JSONObject host = (JSONObject) tmp;
			maps.put(host.getString("id"), host);
		}

		return maps;
	}

	private JSONArray listHostInfoFromMGM(String siteId) throws APIException {
		String urlPattern = "/{0}/hosts";
		String url = MessageFormat.format(urlPattern, SysConstants.MGM_VERSION);
		RespJson httpRespJson = sendHttpGet(siteId, SysConstants.INTERFACE_TYPE_MGM, url);
		if (httpRespJson.getStatus() == HttpStatus.SC_OK) {
			return ((JSONArray) httpRespJson.getData());
		} else {
			throw new APIException(httpRespJson.getMsg());
		}
	}

}
